package com.liwujie.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

@Component
public class OrderRedisUtil {

    private final RedisTemplate<String, Object> redisTemplate;
    private final StringRedisTemplate stringRedisTemplate;

    // 订单相关缓存key前缀
    private static final String ORDER_CONFIRM_PREFIX = "order:confirm:";
    private static final String ORDER_SUBMIT_LOCK_PREFIX = "order:submit:lock:";

    @Autowired
    public OrderRedisUtil(RedisTemplate<String, Object> redisTemplate,
                          StringRedisTemplate stringRedisTemplate) {
        this.redisTemplate = redisTemplate;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 缓存订单确认信息
     */
    public void cacheOrderConfirm(Long userId, Object confirmData) {
        String key = ORDER_CONFIRM_PREFIX + userId;
        redisTemplate.opsForValue().set(key, confirmData, 30, TimeUnit.MINUTES);
    }

    /**
     * 获取缓存的订单确认信息
     */
    public <T> T getOrderConfirm(Long userId, Class<T> clazz) {
        String key = ORDER_CONFIRM_PREFIX + userId;
        return clazz.cast(redisTemplate.opsForValue().get(key));
    }

    /**
     * 删除订单确认缓存
     */
    public void deleteOrderConfirm(Long userId) {
        String key = ORDER_CONFIRM_PREFIX + userId;
        redisTemplate.delete(key);
    }

    /**
     * 尝试获取订单提交锁（防止重复提交）
     */
    public boolean tryLockSubmit(Long userId) {
        String key = ORDER_SUBMIT_LOCK_PREFIX + userId;
        return stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 30, TimeUnit.SECONDS);
    }

    /**
     * 释放订单提交锁
     */
    public void unlockSubmit(Long userId) {
        String key = ORDER_SUBMIT_LOCK_PREFIX + userId;
        stringRedisTemplate.delete(key);
    }

    /**
     * 检查并删除订单确认标记（原子操作）
     */
    public boolean checkAndDeleteConfirm(Long userId) {
        String key = ORDER_CONFIRM_PREFIX + userId;
        String script = "if redis.call('get', KEYS[1]) ~= false then return redis.call('del', KEYS[1]) else return 0 end";
        Long result = stringRedisTemplate.execute(
                new org.springframework.data.redis.core.script.DefaultRedisScript<>(script, Long.class),
                Collections.singletonList(key)
        );
        return result != null && result == 1;
    }
}